#include "gs_icevideoconfig.h"

gs_ICEVideoConfig::gs_ICEVideoConfig(B_GameStateHandler* handler, bool initialConfig) : B_GameState(handler)
{
	using namespace irr;
	newDeviceSettings = initialConfig;
#define BTN_ROW_SPACING  55
#define BTN_W            110
#define BTN_H            50

	//1) initialize GUI
	//load logo
	m_driver->setTextureCreationFlag(irr::video::ETCF_OPTIMIZED_FOR_QUALITY, true);
	m_pIceLogo = m_driver->getTexture("data/ice.bmp");
	if(m_pIceLogo) m_driver->makeColorKeyTexture(m_pIceLogo, irr::core::position2d< irr::s32 >(0,0) );

	//TODO: get resolution from device, and set pos according to that
	int btn_x = 100 ;
	int btn_y = 10 ;

	//set title text
	m_env->getSkin()->setFont(m_env->getBuiltInFont());
	// In older versions of Irrlicht, true and core::rect() are switched
	m_txt_title = m_env->addStaticText ( L"ICE v3.0 Device Configuration",
		core::rect<int32>(btn_x, btn_y, btn_x + BTN_W*2, btn_y + BTN_H),  true) ;

	//create device type list box
	btn_y += BTN_ROW_SPACING; // move down
	m_lst_dev = m_env->addListBox(core::rect<s32>(btn_x, btn_y, btn_x + BTN_W, btn_y + BTN_H*2),
		0, GSCNF_GUI_LST_DEV);
	btn_y += BTN_ROW_SPACING; //allow for extra height of list box

	//create color depths list box
	btn_y += BTN_ROW_SPACING; // move down
	m_lst_color = m_env->addListBox(core::rect<s32>(btn_x, btn_y, btn_x + BTN_W, btn_y + BTN_H),
		0, GSCNF_GUI_LST_COLOR);
	//btn_y += BTN_ROW_SPACING; //allow for extra height of list box

	//create resolutions list box
	btn_y += BTN_ROW_SPACING; // move down
	m_lst_res = m_env->addListBox(core::rect<s32>(btn_x, btn_y, btn_x + BTN_W, btn_y + BTN_H*2),
		0, GSCNF_GUI_LST_RES);
	btn_y += BTN_ROW_SPACING; //allow for extra height of list box

	//create fullscreen check box
	btn_y += BTN_ROW_SPACING; // move down
	m_chk_fullscreen = m_env->addCheckBox( false, //(ICE_Options::getConfig("fullscreen") == "T"),
		core::rect<s32>(btn_x, btn_y, btn_x + BTN_W*2, btn_y + BTN_H),  0,  GSCNF_GUI_CHK_FULLSCRN,
		L"Fullscreen" );

	//set OK button
	btn_y += BTN_ROW_SPACING; // move down
	m_btn_ok = m_env->addButton(core::rect<s32>(btn_x, btn_y, btn_x + BTN_W, btn_y + BTN_H), 0,
		GSCNF_GUI_BTN_OK, L"OK");



	//2)read config options from file

	TiXmlDocument doc;
	doc.LoadFile(GS_CONFIG_FILE);
	TiXmlNode* node = NULL;
	TiXmlElement *elem = NULL;
	TiXmlElement *option = NULL;
	TiXmlAttribute *attr = NULL;
	wchar_t _buffer[1024];
	irr::s32 idx;

	node = doc.FirstChild( "configOptions" );
	if(!node) {
		printf("gs_Configure: ERROR! malformed config file, could not find configOptions node");
		return;
	}

	elem = node->FirstChild("Resolutions")->ToElement();
	if(!elem) {
		printf("gs_Configure: WARNING! malformed config file, could not find Resolutions node");
		return;
	}
	option = elem->FirstChildElement();
	while( option != NULL ) {
		attr = option->FirstAttribute();

		mbstowcs(_buffer, attr->Value(), 1024 );
		idx = m_lst_res->addItem( _buffer );
		//if this is the current resolution choice, select it by default
		if(std::string(attr->Value()) == ICE_Options::getConfig("resolution") ) {
			m_lst_res->setSelected(idx);
		}
		option = option->NextSiblingElement();
	}

	elem = node->FirstChild("ColorDepths")->ToElement();
	if(!elem) {
		printf("gs_Configure: WARNING! malformed config file, could not find ColorDepths node");
		return;
	}
	option = elem->FirstChildElement();
	while( option != NULL ) {
		attr = option->FirstAttribute();

		mbstowcs(_buffer, attr->Value(), 1024 );
		idx = m_lst_color->addItem( _buffer );
		//if this is the current resolution choice, select it by default
		if(std::string(attr->Value()) == ICE_Options::getConfig("colordepth") ) {
			m_lst_color->setSelected(idx);
		}
		option = option->NextSiblingElement();
	}


	elem = node->FirstChild("Devices")->ToElement();
	if(!elem) {
		printf("gs_Configure: WARNING! malformed config file, could not find Devices node");
		return;
	}
	option = elem->FirstChildElement();
	while( option != NULL ) {
		attr = option->FirstAttribute();
		mbstowcs(_buffer, attr->Value(), 1024 );
		idx = m_lst_dev->addItem( _buffer );
		//if this is the current color choice, select it by default
		if(std::string(attr->Value()) == ICE_Options::getConfig("device") ) {
			m_lst_dev->setSelected(idx);
		}
		option = option->NextSiblingElement();
	}
}

gs_ICEVideoConfig::~gs_ICEVideoConfig(void)
{
	// 1) delete GUI objects
	m_btn_ok->remove();
	m_txt_title->remove();
	m_lst_res->remove();
	m_lst_color->remove();
	m_lst_dev->remove();
	m_chk_fullscreen->remove();

	// 2) if settings change, reinit Irrlicht
	//implement driver change here
	if(newDeviceSettings) {
		ICEDBGMSG( "changing device settings\n" );
		m_device->closeDevice();
		m_device->drop();
		((ICEFrameworkEngine*)m_handler)->m_device = NULL;
		ICEDBGMSG( "old device closed\n" );
		//in older versions of irrlicht E_DRIVER_TYPE is EDriverType
		irr::video::E_DRIVER_TYPE device_type;
		int res_x, res_y;
		bool fullscreen = ICE_Options::getConfig("fullscreen") == "T" ? true : false;
		int colordepth = ICE_Options::getConfig("colordepth") == "16" ? 16 : 32 ;
		std::string res, device;
		res = ICE_Options::getConfig("resolution");
ICEDBGMSG( "using res: %s  \n", device.c_str() );
		if(res == "640x480") {
			res_x = 640; res_y = 480;
		}else if( res == "800x600" ) {
			res_x = 800; res_y = 600;
		}else if( res == "1024x768" ) {
			res_x = 1024; res_y = 768;
		}
		device = ICE_Options::getConfig("device");
		ICEDBGMSG( "using device: %s  \n", device.c_str() );
		if(device == "OpenGL") {
			device_type = irr::video::EDT_OPENGL;
		}else if(device == "Direct3D8") {
			device_type = irr::video::EDT_DIRECT3D8;
		}else if(device == "Direct3D9") {
			device_type = irr::video::EDT_DIRECT3D9;
		}else if(device == "IrrlichtSoftware") {
			device_type = irr::video::EDT_SOFTWARE;
		}else {
            device_type = irr::video::EDT_SOFTWARE2;
        }
		ICEDBGMSG( "starting up new device...\n" );

		//reinitialize device
		if(
			//casting like this is bad, but neccesary in this instance
			((ICEFrameworkEngine*)m_handler)->Init(NULL, device_type,res_x,res_y,fullscreen,colordepth, false, true)
		){
			ICEDBGMSG( "new device SUCCESSFUL!\n" );
			ICE_Options::setConfig("configured", "T");
			ICE_Options::Save();
		}else {
			ICEDBGMSG( "new device FAILED\n" );
		}//end if-else: device success/fail
	}else {
ICEDBGMSG("set configured = true \n");
		ICE_Options::setConfig("configured", "T");
		ICE_Options::Save();
	}//end if-else: newDeviceSettings (reinit), or defaults chosen

}

void gs_ICEVideoConfig::Render() {
	using namespace irr;
	m_driver->beginScene(true, true, video::SColor(0,150,150,165));

	if(m_pIceLogo) m_driver->draw2DImage(m_pIceLogo,
		irr::core::position2d< irr::s32 >(50,50),
		irr::core::rect< irr::s32 >(0,0,32,32),
		0,
		irr::video::SColor(255, 255, 255, 255),
		true
		);

	m_env->drawAll();

	m_driver->endScene();
}
bool gs_ICEVideoConfig::onEvent(irr::SEvent event) {
	using namespace irr;
	using namespace gui;

	if( event.EventType == irr::EET_KEY_INPUT_EVENT && event.KeyInput.PressedDown ) {
		if( event.KeyInput.Key == irr::KEY_ESCAPE ) {
            newDeviceSettings = false;
			m_handler->RequestStateChange("VIDEO_CONFIG_EXIT");
			return true;
		}
    }

	if (event.EventType == EET_GUI_EVENT) {
		s32 id = event.GUIEvent.Caller->getID();
		switch(event.GUIEvent.EventType) {
		case EGET_CHECKBOX_CHANGED:
			if(id == GSCNF_GUI_CHK_FULLSCRN) {
				if(ICE_Options::getConfig("fullscreen") == "T")
					ICE_Options::setConfig("fullscreen", "F");
				else
					ICE_Options::setConfig("fullscreen", "T");

				newDeviceSettings = true;
				return true;
			}

			break;
		case EGET_BUTTON_CLICKED:
			if(id == GSCNF_GUI_BTN_OK) {
				m_handler->RequestStateChange("VIDEO_CONFIG_EXIT");
				return true;
			}
			break;

		case EGET_LISTBOX_CHANGED:
			if(id == GSCNF_GUI_LST_RES) {
				char c_buffer[64];
				wcstombs(c_buffer, m_lst_res->getListItem(m_lst_res->getSelected()), 64);
	ICEDBGMSG("resolution chosen: %s", c_buffer);
				ICE_Options::setConfig("resolution", c_buffer);
ICEDBGMSG("resolution chosen: %s", ICE_Options::getConfig("resolution").c_str() );
				newDeviceSettings = true;
				return true; //if supported list id
			}else if( id == GSCNF_GUI_LST_COLOR) {
				char c_buffer[64];
				wcstombs(c_buffer, m_lst_color->getListItem(m_lst_color->getSelected()), 64);
				ICE_Options::setConfig("colordepth", c_buffer);
				newDeviceSettings = true;
				return true; //if supported list id
			}else if( id == GSCNF_GUI_LST_DEV) {
				char c_buffer[64];
				wcstombs(c_buffer, m_lst_dev->getListItem(m_lst_dev->getSelected()), 64);
				ICE_Options::setConfig("device", c_buffer);
				newDeviceSettings = true;
				return true; //if supported list id
			}
			break;
		}//end switch: type of GUI event
	}//end if: GUI event

	return false;
}

void gs_ICEVideoConfig::Update() {
	Render();
}
